Celem projektu jest przeprowadzenie wizualizacji obiektów n-wymiarowych w przestrzeni m-wymiarowej (m<n) za pomocą różnych technik skalowania wielowymiarowego (MDS) i analizy składowych głównych (PCA), aby zredukować ilość zmiennych i przestawić je w postaci 2-wymiarowej lub 3-wymiarowej.
W tym projekcie korzystam ze zbioru wbudowanego w R, jakim jest mtcars. Analiza obejmie także eksploracyjną analizę danych (EDA).
Zastosowane biblioteki:
library(psych)
library(corrplot)
library(RColorBrewer)
library(magrittr)
library(dplyr)
library(ggpubr)
library(knitr)
library(plotly)
library(vegan)
library(tidyr)
library(MASS)
library(tibble)
library(ggplot2)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
Zbiór mtcars zawiera dane o 32 samochodach, a każda kolumna reprezentuje jedną cechę samochodu. Oto cechy w zbiorze:
mpg: Mile per gallon (spalanie w milach na galon, przyjmuję że USA); czyli ok 1,72l/km
cyl: Liczba cylindrów
disp: Pojemność silnika (w calach sześciennych)
hp: Konie mechaniczne
drat: Przełożenie tylnej osi
wt: Waga samochodu (w tysiącach funtów)
qsec: Czas przejazdu ćwierć mili (w sekundach)
vs: Silnik (0 = V-engine, 1 = straight engine)
am: Typ skrzyni biegów (0 = automatyczna, 1 = manualna)
gear: Liczba biegów
carb: Liczba gaźników (gaźnik to podzespół mający za zadanie wytworzyć gotową mieszankę powietrzno-paliwową w benzynowym silniku spalinowym, która następnie trafia do cylindrów, aby ulec spaleniu i móc wytworzyć energię niezbędną do napędzenia kół pojazdu)
Sprawdzenie struktury danych:
## 'data.frame': 32 obs. of 11 variables:
## $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
## $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
## $ disp: num 160 160 108 258 360 ...
## $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
## $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
## $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
## $ qsec: num 16.5 17 18.6 19.4 17 ...
## $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
## $ am : num 1 1 1 0 0 0 0 0 0 0 ...
## $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
## $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
Wszystkie dane są numeryczne.
## vars n mean sd median trimmed mad min max range skew
## mpg 1 32 20.09 6.03 19.20 19.70 5.41 10.40 33.90 23.50 0.61
## cyl 2 32 6.19 1.79 6.00 6.23 2.97 4.00 8.00 4.00 -0.17
## disp 3 32 230.72 123.94 196.30 222.52 140.48 71.10 472.00 400.90 0.38
## hp 4 32 146.69 68.56 123.00 141.19 77.10 52.00 335.00 283.00 0.73
## drat 5 32 3.60 0.53 3.70 3.58 0.70 2.76 4.93 2.17 0.27
## wt 6 32 3.22 0.98 3.33 3.15 0.77 1.51 5.42 3.91 0.42
## qsec 7 32 17.85 1.79 17.71 17.83 1.42 14.50 22.90 8.40 0.37
## vs 8 32 0.44 0.50 0.00 0.42 0.00 0.00 1.00 1.00 0.24
## am 9 32 0.41 0.50 0.00 0.38 0.00 0.00 1.00 1.00 0.36
## gear 10 32 3.69 0.74 4.00 3.62 1.48 3.00 5.00 2.00 0.53
## carb 11 32 2.81 1.62 2.00 2.65 1.48 1.00 8.00 7.00 1.05
## kurtosis se
## mpg -0.37 1.07
## cyl -1.76 0.32
## disp -1.21 21.91
## hp -0.14 12.12
## drat -0.71 0.09
## wt -0.02 0.17
## qsec 0.34 0.32
## vs -2.00 0.09
## am -1.92 0.09
## gear -1.07 0.13
## carb 1.26 0.29
Interpretacja najważniejszych cech zbioru:
Średnia spalania wynosi 20,09 mil/galon, czyli 11,71l/100km. Największe spalanie wynosi 10,4 mil/galon, co w przeliczeniu daje 22,62l/100km.
Vs (silnik) i am (typ skrzyni biegów) mają najmniejsze zróżnicowania, gdyz są to jedyne zmienne binarne w tym zbiorze. Jest przewaga skrzyń automatycznych i silników V-engine, ale nie bardzo duża.
Samochody są: 3, 4, 6, 8 lub nawet 12- cylindrowe. W tym zbiorze występują 4, 6 i 8-cylindrowe i ich mediana wynosi 6.
Występuje duże zróżnicowanie jest w kolumnie disp, która oznacza pojemność silnika. Najmniejsza pojemność silnika to 71,1 cali sześciennych i jest w samochodzie Toyota Corolla, a największa to 472 cali sześciennych występująca w Cadillac Fleetwood
Średnia koni mechanicznych (hp) wynosi 146,69, przy czym jest spore odchylenie standardowe wynoszące 68,56 konia mechanicznego.
Średnia waga samochodu (wt) to 3,22 tysiąca funtów i także jest wysokie odchylenie standardowe (0,98), czyli samochody dość znacznie różnią się wagą.
Średnia liczba biegów wynosi 3,69, przy czym najmniej to 3 a najwięcej to 5, więc jest bardz mały zakres, stąd nieduże zróżnicowanie
Liczba gaźników w samochodach jest bardzo zróżnicowana, średnia to 2,81 a odchylenie standardowe 1,62
Sprawdzenie brakujących danych:
## [1] 0
Brak brakujących danych.
W rozkładzie spalania widać, że większa ilość samochodów jest po lewej stronie histogramu, co znaczy że większość aut ma wyższe spalanie (>25 mil/galon).
Rozkład wagi aut jest równomiernie rozłożony do wagi 3, następnie widać że najwięcej aut ma wagę od 3-3.5 tysiąca funtów, a także spora liczba aut ma wagę pomiędzy 3.5-4. Wagę powyżej 4 tysiącą funtów ma zdecydowana mniejszość aut (12,5%)
W rozkładzie mocy można zauważyć tendencję liniową, liczba samochodów maleje wraz ze zwiększaniem się liczby koni mechanicznych
Rozkład przełożenia przypomina rozkład normalny, najwięcej aut ma przełozenie pomiędzy 3.5-4
Na rozkładzie cylindrów, można zauważyć, że są tylko samochody z 4,6 i 8 cylindrami, najwięcej jest 8-cylindowych.
Rozkład pojemności silnika jest zróżnicowany, lecz najwięcej aut ma pojemność silnika od 100 do 150 cali sześciennych.
Rozkład czasu przejazdu ćwierć mili w sekundach przypomina rozkład normalny, ze zdecydowaną większością ilością aut, które przejeżdżają w zakresie 16-20 na sekundę.
Z rozkładu gażników wynika, że zdecydowana większość (ok 12 samochodów) ma dwa gaźniki.
W rozkładzie liczby biegów widać, że najwięcej jest aut, które mają 3 lub 4 biegi.
W rozkładzie silników przeważają silniki V-engine i bardzo podobny jest wykres typu skrzyni biegów, gdzie widać przewagę automatycznej skrzyni.
Trzy zmienne (oprócz disp) mają wartości odstające. Zatem na całym zbiorze danych zastosuję zasadę 3 sigm w celu usunięcia wartości odstających:
# Funkcja do usuwania wartości odstających
remove_outliers <- function(df) {
for (col in colnames(df)) {
# Obliczanie średniej i odchylenia standardowego
mean_val <- mean(df[[col]], na.rm = TRUE)
sd_val <- sd(df[[col]], na.rm = TRUE)
# Zakres dozwolonych wartości: średnia ± 3 odchylenia standardowe
lower_limit <- mean_val - 3 * sd_val
upper_limit <- mean_val + 3 * sd_val
# Usuwanie wierszy, które mają wartości odstające w tej kolumnie
df <- df[df[[col]] >= lower_limit & df[[col]] <= upper_limit, ]
}
return(df)
}
# Usunięcie wartości odstających
mtcars_cleaned <- remove_outliers(mtcars)
# Wyświetlenie liczby oczyszczonych danych
nrow(mtcars_cleaned)
## [1] 31
mtcars<-mtcars_cleaned
Zatem został usunięty 1 obiekt.
Występuję dużo silnych zależności między zmiennymi. Kilka wniosków:
Największa zależność jest między liczbą cylindrów a pojemnością silnika. Wraz ze wzrostem pojemności silnika wzrasta liczba cylindrów. Podobna, silna zależność jest także np. między liczbą koni mechanicznych a liczbą cylindrów, pojemnością silnika a wagą samochodu, liczbą koni mechanicznych a pojemnością silnika.
Silne zależności typu wraz ze wzrostem jednej zmiennej, maleje druga, występują między innymi pomiędzy: spalaniek a liczbą koni, spalaniem a wagą auta, spalaniem a liczbą cylindrów, spalaniem a pojemnością silnika.
Najsłabsze zależności są pomiędzy: liczbą koni mechanicznych a liczbą biegów, liczbą ganików a typem skrzyni, przełożeniem a liczbą gaźników
Celem jest zmniejszenie wymiaru danych przy jak najmniejszym zniekształceniu prawdziwych odległości. Posługuje się odległościami euklidesowymi między obiektami. Dodany także został współczynnik Stress, który w analizie MDS jest miarą niedopasowania odwzorowania danych wielowymiarowych na płaszczyźnie (lub w przestrzeni o zmniejszonym wymiarze). Ocenia, jak dobrze odległości między punktami w oryginalnej przestrzeni wielowymiarowej odpowiadają odległościom w przestrzeni o zmniejszonym wymiarze.
Należy zauważyć, że jest to bardzo podobne do analizy PCA lub czynnikowej, ale wykorzystuje macierz odległości, a nie macierz korelacji jako dane wejściowe.
“Problemem klasycznego skalowania (cmdscale) jest to, że zakłada ono odległości metryczne i dopasowuje do nich reprezentację przestrzenną. Na przykład, być może uważamy, że mamy błąd w naszym pomiarze, a te błędy mogą być nieliniowe. Albo może nie możemy liczyć na nic poza wartościami porządkowymi naszej miary odmienności.” (żródło: “https://pages.mtu.edu/~shanem/psy5220/daily/Day16/MDS.html#sammons-non-linear-scaling-method”)
Zaimplementowanie:
# Compute MDS with cmdscale
dist_matrix <- dist(mtcars) # w tej funkcji liczy odgl. euklidesowa
mds_result <- cmdscale(dist_matrix, eig = TRUE, k = 2) # standaryzacja
# Extract coordinates
mds <- as.data.frame(mds_result$points)
colnames(mds) <- c("Dim.1", "Dim.2")
# Add car names as a column
mds$Car <- rownames(mtcars)
# Calculate distances in reduced 2D space
reduced_dist <- dist(mds[, c("Dim.1", "Dim.2")])
# Compute stress
stress <- sqrt(sum((dist_matrix - reduced_dist)^2) / sum(dist_matrix^2))
# Plot MDS
ggscatter(mds, x = "Dim.1", y = "Dim.2",
label = "Car", # Use the 'Car' column for labels
size = 1,
repel = TRUE)
{#kod na podstawie: https://www.sthda.com/english/articles/31-principal-component-methods-in-r-practical-guide/122-multidimensional-scaling-#essentials-algorithms-and-r-code/#visualizing-a-correlation-matrix-using-multidimensional-scaling}
Widać pewne szczególne skupisko. Poniżej implementacja analizy skupień, aby łatwiej pogrupować wyniki:
library(ggplot2)
library(ggpubr)
# Compute MDS with cmdscale
dist_matrix <- dist(mtcars) # Distance matrix (Euclidean)
mds_result <- cmdscale(dist_matrix, eig = TRUE, k = 2) # Perform MDS (2 dimensions)
# Extract coordinates
mds <- as.data.frame(mds_result$points)
colnames(mds) <- c("Dim.1", "Dim.2")
# Add car names as a column
mds$Car <- rownames(mtcars)
# Calculate distances in reduced 2D space
reduced_dist <- dist(mds[, c("Dim.1", "Dim.2")])
# Compute stress
stress <- sqrt(sum((dist_matrix - reduced_dist)^2) / sum(dist_matrix^2))
# Perform K-means clustering on the 2D MDS coordinates (choose 3 clusters as an example)
set.seed(123) # Set seed for reproducibility
clust <- kmeans(mds[, c("Dim.1", "Dim.2")], centers = 3)$cluster
mds$Cluster <- as.factor(clust)
# Plot MDS with cluster results
ggscatter(mds, x = "Dim.1", y = "Dim.2",
label = "Car", # Use the 'Car' column for labels
color = "Cluster", # Color points by cluster
palette = "jco", # Color palette
size = 1,
ellipse = TRUE, # Add convex hulls for each cluster
ellipse.type = "convex",
repel = TRUE) + # Avoid label overlap
ggtitle(paste("MDS Plot with K-means Clustering (Stress:", round(stress, 5), ")")) +
theme_minimal()
Zgodnie z interpretacją Kruskala jakość dopasowania danych jest bardzo dobra (stress<0.05). Statystyki w wybranych zmiennych różnią się pomiędzy klastrami a wewnątrz nich są zbliżone, także na tej podstawie też można stwierdzić dobre pogrupowanie skalowania danych o samochodach. Skutecznie udało się zmniejszyć ilośc wymiarów do pogrupowania aut.
Przeprowadzenie MDS w trzech wymiarach i pogrupowanie (interaktywny wykres):
Współczynnik Stress jest ponad 3 razy mniejszy niż przy zastosowaniu dwóch wymiarów. Na wykresie 3D szczególnie widać podobieństwo samochodów marki Mercedes w przydzielonych grupach, także można rzec, że Mazda RX4 Wag nie różni się od Mazdy RX4. Zatem sprawdzę ich wartości:
## Car mpg cyl disp hp drat wt qsec vs am gear carb
## 1 Mazda RX4 21 6 160 110 3.9 2.620 16.46 0 1 4 4
## 2 Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
Jak widać, z tych wartości wynika, że te samochody są można rzec prawie takie same. Teraz na tej podstawie porównam również auta marki Mercedes, które należą do trzech grup:
## Car mpg cyl disp hp drat wt qsec vs am gear carb
## 1 Merc 240D 24.4 4 146.7 62 3.69 3.19 20.0 1 0 4 2
## 2 Merc 230 22.8 4 140.8 95 3.92 3.15 22.9 1 0 4 2
## 3 Merc 280 19.2 6 167.6 123 3.92 3.44 18.3 1 0 4 4
## 4 Merc 280C 17.8 6 167.6 123 3.92 3.44 18.9 1 0 4 4
## 5 Merc 450SE 16.4 8 275.8 180 3.07 4.07 17.4 0 0 3 3
## 6 Merc 450SL 17.3 8 275.8 180 3.07 3.73 17.6 0 0 3 3
## 7 Merc 450SLC 15.2 8 275.8 180 3.07 3.78 18.0 0 0 3 3
Mercedesy należące do klastra 1 różnią się jedynie spalaniem (mpg), lecz nie wiele. Mercedesy należące do grupy 2 także różnią się spalaniem i wagą, ale są to niewielkie różnice. Od Mercedesów z pierwszej grupy różnią się liczbą gaźników (mają 3 a nie 4), silnikiem, zdecydowanie większą liczbą koni mechanicznych, ważą więcej, mają 8 cylindrów zamiast 6. Charakteryzują się dużą pojemnością silnika, niższymi wartościami przełozenia osi tylnej. Mercedesy należace do grupy 3 są unikatowe w porównaniu do poprzednich. Wyróżniają się najniższym spalaniem, najmniejszą liczbą cylindrów, najmniejszą pojemnością silnika, najmniejszą liczbą koni mechanicznych, z najmniejszą wagą, najdłużej rozpędzające się.
Wniosek: Metoda MDS umożliwia świetne przedstawienie podobieństwa między obiektami w wybranym zbiorze danych. W połączeniu z analizą skupień, samochody zostały świetnie pogrupowane.
Zalety metody:
na tym zbiorze danych świetnie się sprawdziła, wyniki są czytelnie przedstawione i udało skutecznie się pozbyć wielowymiarowości
zachowuje wzajemne odległości (lub podobieństwa/dysymilarności) między obiektami, umożliwiając dokładne odwzorowanie ich relacji w zredukowanej przestrzeni.
można skuteczniej pogrupować w klastry
brak założeń o normalności danych
Wady:
wymaga danych metrycznych, tj. takich, które spełniają warunki metryki (np. odległość Euklidesowa)
wrażliwość na dane odstające
brak interpretacji osi
wrażliwośc na wybór miary odległości
W tej metodzie także została użyta odległość euklidesowa. Różni się od poprzedniej poprzez dodanie wag i jest bardziej elastyczna, ponieważ nie zakłada, że odległości między punktami muszą być metryczne. Skalowanie Sammona jest szczególnie przydatne, gdy zależy nam na zachowaniu odległości lokalnych i względnych.
Implementacja i wyniki:
library(MASS) # Pakiet do skalowania Sammona
library(ggplot2) # Do wizualizacji wyników
library(dplyr) # Do manipulacji danymi
# Oblicz odległości (euklidesowe)
dist_matrix <- dist(mtcars)
# skalowanie Sammona (redukcja do 2 wymiarów)
sammon_result <- sammon(dist_matrix, k = 2)
## Initial stress : 0.00016
## stress after 10 iters: 0.00002, magic = 0.500
## stress after 20 iters: 0.00002, magic = 0.500
# współrzędne w 2 wymiarach
sammon_mds <- as.data.frame(sammon_result$points)
colnames(sammon_mds) <- c("Dim.1", "Dim.2")
#nazwy samochodów
sammon_mds$Car <- mtcars$Car
# współczynnik stress
reduced_dist <- dist(sammon_mds[, c("Dim.1", "Dim.2")])
stress <- sqrt(sum((dist_matrix - reduced_dist)^2) / sum(dist_matrix^2))
# Zastosowanie analizy skupień (K-means)
set.seed(123) # Ustalamy ziarno losowości dla reprodukowalności
kmeans_result <- kmeans(sammon_mds[, c("Dim.1", "Dim.2")], centers = 3) # Można zmienić liczbę klastrów
# Dodanie wyników klasteryzacji do danych
sammon_mds$Cluster <- as.factor(kmeans_result$cluster)
# Dodanie kolumny Cluster do oryginalnego zbioru mtcars
mtcars$ClusterSammon <- clust
# Wizualizacja wyników na wykresie
ggplot(sammon_mds, aes(x = Dim.1, y = Dim.2, color = Cluster)) +
geom_point(size = 3) + # Punkty reprezentujące samochody
geom_text(aes(label = Car), vjust = -0.5, hjust = 1.5, size = 3) + # Etykiety samochodów
theme_minimal() +
ggtitle(paste("Sammon Scaling with K-means Clustering (Stress:", round(stress, 5), ")")) + # Dodanie współczynnika stress w tytule
theme(axis.title = element_blank(), axis.text = element_blank()) + # Ukrycie osi
scale_color_manual(values = c("blue", "red", "green")) # Kolory dla klastrów
Współczynnik stresu jest troszkę wyższy niż w klasycznym MDS (0.00196). Porównanie przypisania klastrów:
## [1] 1 1 3 1 2 1 2 3 3 1 1 2 2 2 2 2 2 3 3 3 3 2 2 2 2 3 3 3 2 1 3
## Levels: 1 2 3
## [1] 3 3 2 3 1 3 1 2 2 3 3 1 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 1 3 2
Pierwszy wiersz dotyczy metody skalowania Sammona, drugi klasycznego skalowania. Przypisano tak samo klastry do obiektów. Także ta metoda sprawdziła się równie doskonale, gdyż tak samo dobrze zminimalizowała liczbę wymiarów.
Zalety:
nieliniowość, co pozwala lepiej oddać skomplikowane, nieliniowe relacje w danych
uniwersalność i może być stosowana do różnych typów danych, o ile możliwe jest obliczenie macierzy odległości
Skalowanie Sammona używa miary błędu (stress function), która zmniejsza różnice między oryginalnymi odległościami a ich odpowiednikami w zredukowanej przestrzeni, dzięki czemu końcowy wynik jest bardziej dokładny, choć dokładniejszy wynik wyszedł w klasycznym skalowaniu
Wady:
wrażliwośc na punkty odsjtające
minimalizuje funkcję stresu iteracyjnie (np. algorytmem gradientowym), co może prowadzić do zbieżności do lokalnego minimum, a nie globalnego. Wynik może zależeć od początkowej konfiguracji.
wymaga obliczenia macierzy odległości oraz iteracyjnej optymalizacji, co może być kosztowne obliczeniowo, szczególnie dla dużych zbiorów danych
brak interpretacji osi
dane także zależą od miary odległości
Założeniem jest, że kolejność odległości ma znaczenie, zatem stosuje się odległość kolejności rang. Wyniki współczynnika Stress liczą się do określenia, czy kolejnośc rangi wszystkich odległości parami w rozwiązaniu jest taka sama jak kolejność rangi w podobieństwie. Ta metoda umożliwia skalowanie na danych porządkowych.
Implementacja i wyniki:
library(vegan)
# niemetryczne skalowanie wielowymiarowe (nMDS)
nmds_result <- metaMDS(dist_matrix, k = 2, try = 20, autotransform = FALSE, trace = FALSE) # k = 2 oznacza 2 wymiary w przestrzeni
cat("Best stress value:", nmds_result$stress, "\n")
## Best stress value: 9.985455e-05
# Współrzędne w przestrzeni 2D
nmds_mds <- as.data.frame(nmds_result$points)
colnames(nmds_mds) <- c("Dim.1", "Dim.2")
nmds_mds$Car <- mtcars_with_names$Car
# Zastosowanie analizy skupień (K-means)
set.seed(123) # Ustalamy ziarno losowości dla reprodukowalności
kmeans_result <- kmeans(nmds_mds[, c("Dim.1", "Dim.2")], centers = 3)
# Dodanie wyników klasteryzacji do danych
nmds_mds$Cluster <- as.factor(kmeans_result$cluster)
# Wizualizacja wyników na wykresie
ggplot(nmds_mds, aes(x = Dim.1, y = Dim.2, color = Cluster)) +
geom_point(size = 3) + # Punkty reprezentujące samochody
geom_text(aes(label = Car), vjust = -0.5, hjust = 1.5, size = 3) + # Etykiety samochodów
theme_minimal() +
ggtitle("nMDS (Non-metric Multidimensional Scaling) with K-means Clustering") +
theme(axis.title = element_blank(), axis.text = element_blank()) + # Ukrycie osi
scale_color_manual(values = c("blue", "red", "green")) # Kolory dla klastrów
Klastry zostały przypisane tak samo, lecz nastąpiło “odbicie lustrzane” obiektów. Gdy spojrzymy na Mercedesy 450 (czerwony klastr), to w tej metodzie są narysowane jako jedna kropka, a w poprzedniej widać nałożenie się kilku kropek, skąd wynika że metoda jest mniej dokładna od poprzedniej. Wyniki mniejszej precyzji wydają się intuincyjne jak nie obliczamy “surowych odległości między danymi” tylko odległości między rangami.
Zalety:
zastosowanie do danych niemetrycznych
odporność na wartości odstające
brak założeń dotyczących rozkładu danych np normalności czy liniowości
Wady:
brak interpretacji osi
wrażliwość na wybór miary odległości
mniejsza dokładność w porównaniu do poprzednich metod
wrażliwość na braki w danych
PCA jest techniką redukcji wymiarów, która pozwala na zrozumienie struktury danych poprzez przekształcenie ich na zestaw nowych zmiennych (główne składowe), które są liniowymi kombinacjami oryginalnych zmiennych. W tej metodzie posługujemy się korelacją między zmiennymi, a ze wstępnej analizy danych wynika, że dane są wysoko skorelowane ze sobą, zatem można ich użyć. Główną różnicą pomiędzy PCA a skalowaniem wielowymiarowym jest to, że skalowanie wielowymiarowe tak naprawdę nie wymaga znajomości surowych danych a jedynie odległości pomiędzy obserwacjami. Biorę pod uwagę jak wynika z EDA, że nie wszystkie zmienne mają rozkład normalny, a PCA zakłada rozkład normalny, przez co wyniki moga być gorsze.
PCA nie ma bezpośredniego współczynnika stress, ponieważ jest to technika liniowa, a stress jest używany w analizie nieliniowej, jak w przypadku MDS. Jednak PCA może pomóc w zrozumieniu struktury danych, koncentrując się na wariancji wyjaśnionej przez kolejne składowe.
Test Barletta, aby sprawdzić istotnośc korelacji:
##
## Bartlett test of homogeneity of variances
##
## data: mtcars
## Bartlett's K-squared = 1909.5, df = 10, p-value < 2.2e-16
Wartość p-value jest mniejsza od 2.2e-16, zatem jest mniejsza od 0,05 poziomu istotności. Odrzucam H0 o równości macierzy kowariancji, zmienne w zestawie danych sa dostatecznie powiązane, aby wykonać PCA.
Kolejny test - obliczenie współczynnika KMO
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = mtcars)
## Overall MSA = 0.83
## MSA for each item =
## mpg cyl disp hp drat wt qsec vs am gear carb
## 0.93 0.90 0.76 0.84 0.95 0.74 0.74 0.91 0.88 0.85 0.62
W zależności od żródła uważa się, że do analizy uprawnia KMO>0.5 (>0.7). Dane mtcars spełniają także ten warunek - ogólny wynik to 0.83.
W implementacji zostało uwzględnione skalowanie danych.:
library(ggplot2)
data("mtcars")
# Normalizacja danych przed zastosowaniem PCA (standaryzacja)
mtcars_scaled <- scale(mtcars)
# Przeprowadzenie PCA
pca_result <- prcomp(mtcars_scaled, center = TRUE, scale. = TRUE)
# Wykres wariancji wyjaśnionej przez główne składowe
screeplot(pca_result, main = "Wykres łamańca (PCA)", col = "blue", lwd = 2)
Scree plot (wykres łamańca) to wykres używany głównie w analizie składowych głównych (PCA) oraz w innych technikach redukcji wymiaru, który pomaga ocenić liczbę składowych, które warto zatrzymać w analizie. W kontekście PCA, wykres ten pokazuje wariancję wyjaśnianą przez każdą z kolejnych składowych głównych.
Wykres łamańca - opis:
Oś X: przedstawia kolejność składowych głównych (np. 1, 2, 3,…).
Oś Y: przedstawia ilość wariancji (lub wartości własne) wyjaśnianej przez każdą składową.
“Zgięcie” wykresu: Na wykresie scree plot często pojawia się punkt, w którym wykres przestaje gwałtownie opadać i zaczyna stabilizować się, tworząc “łamaniec”. W tym miejscu następuje wyraźna zmiana w nachyleniu wykresu. To zgięcie zwykle wskazuje na liczbę składowych, które należy zachować w dalszej analizie. Zwykle w tym miejscu podejmuje się decyzję, by zatrzymać składowe główne, które wyjaśniają znaczną część wariancji. Widać to, po drugim słupku
“Odcinek poziomy”: Po zgięciu wykres może przejść w bardziej poziomą część, co oznacza, że kolejne składowe wyjaśniają już tylko bardzo małą część wariancji i ich dodawanie nie wnosi istotnych informacji. Zaczyna się od trzeciego słupka.
Widać, że pierwsza składowa wyjaśnia ponad 60% wariancji, jest najistotniejsza, druga blisko 30%, stąd wybrano dwie pierwsze składowe.
Sprawdzenie ładunków składowych (zmienne wpływające na poszczególne PC):
## PC1 PC2 PC3 PC4 PC5 PC6
## mpg -0.3625305 0.01612440 -0.22574419 -0.022540255 -0.10284468 -0.10879743
## cyl 0.3739160 0.04374371 -0.17531118 -0.002591838 -0.05848381 0.16855369
## disp 0.3681852 -0.04932413 -0.06148414 0.256607885 -0.39399530 -0.33616451
## hp 0.3300569 0.24878402 0.14001476 -0.067676157 -0.54004744 0.07143563
## drat -0.2941514 0.27469408 0.16118879 0.854828743 -0.07732727 0.24449705
## wt 0.3461033 -0.14303825 0.34181851 0.245899314 0.07502912 -0.46493964
## qsec -0.2004563 -0.46337482 0.40316904 0.068076532 0.16466591 -0.33048032
## vs -0.3065113 -0.23164699 0.42881517 -0.214848616 -0.59953955 0.19401702
## am -0.2349429 0.42941765 -0.20576657 -0.030462908 -0.08978128 -0.57081745
## gear -0.2069162 0.46234863 0.28977993 -0.264690521 -0.04832960 -0.24356284
## carb 0.2140177 0.41357106 0.52854459 -0.126789179 0.36131875 0.18352168
## PC7 PC8 PC9 PC10 PC11
## mpg 0.367723810 0.754091423 -0.235701617 -0.13928524 -0.124895628
## cyl 0.057277736 0.230824925 -0.054035270 0.84641949 -0.140695441
## disp 0.214303077 -0.001142134 -0.198427848 -0.04937979 0.660606481
## hp -0.001495989 0.222358441 0.575830072 -0.24782351 -0.256492062
## drat 0.021119857 -0.032193501 0.046901228 0.10149369 -0.039530246
## wt -0.020668302 0.008571929 -0.359498251 -0.09439426 -0.567448697
## qsec 0.050010522 0.231840021 0.528377185 0.27067295 0.181361780
## vs -0.265780836 -0.025935128 -0.358582624 0.15903909 0.008414634
## am -0.587305101 0.059746952 0.047403982 0.17778541 0.029823537
## gear 0.605097617 -0.336150240 0.001735039 0.21382515 -0.053507085
## carb -0.174603192 0.395629107 -0.170640677 -0.07225950 0.319594676
PC1 (Pierwsza główna składowa):
Zmienna cyl (0.37) ma największy
wpływ na PC1, co sugeruje, że liczba cylindrów w silniku ma dużą wagę w
tej składowej.
Zmienna mpg (-0.36) również ma
silny wpływ na PC1, wskazując, że spalanie paliwa (mpg) jest ważnym
czynnikiem w tej składowej.
Zmienna disp (0.37) i
wt (0.35) również mają silny wpływ na
PC1.
PC2 (Druga główna składowa):
Zmienna am (0.43) ma największy
wpływ na PC2, co sugeruje, że typ skrzyni biegów (automatyczna/manualna)
ma dużą wagę w tej składowej.
Zmienna gear (0.46) ma także duży
wpływ na PC2, co może wskazywać na związek z liczbą biegów.
Zmienna qsec (-0.46) wpływa również
na PC2, sugerując, że czas przyspieszenia ma pewne znaczenie w tej
składowej.
Implementacja biplotu:
# Biplot - wizualizacja wyników PCA
# Zwiększenie rozmiaru wykresu
par(mar = c(4, 4, 2,2)) # Zwiększenie marginesów, aby wykres miał więcej przestrzeni
# Tworzenie biplotu
biplot(pca_result, cex = 0.5) # Zmniejszenie rozmiaru punktów tekstowych, aby były czytelne
Interpretacja głównych składowych (PC1, PC2):
PC1: Na osi PC1 są wyświetlane zmienne, które wyjaśniają największą część wariancji w danych. Na wykresie widać, że zmienne hp, cyl, disp, mpg i am mają na nią największy wpływ, co potwierdza wcześniejsza analiza.
PC2: PC2 reprezentuje drugą największą część wariancji w danych. Zmienne są ważne dla tej składowej: gear, am, drat, co potwierdza wczesniejsza analiza.
Można zauważyć, które zmienne miały największy wpływ na rozmieszczenie aut w przestrzeni głownych składowych tj
Porsche 914-2 - zmienne gear i am,
Lotus Europa - zmienna drat
Merc 230 i Toyota Corona - zmienna qsec
# dane PCA i nazwy samochodów
pca_data <- as.data.frame(pca_result$x)
pca_data$Car <- rownames(mtcars) # Dodanie nazw samochodów do danych
# (K-means) na pierwszych dwóch głównych składowych
set.seed(123)
kmeans_result <- kmeans(pca_data[, c("PC1", "PC2")], centers = 3) # 3 klastry
# Dodanie wyników analizy skupień do danych PCA
pca_data$Cluster <- as.factor(kmeans_result$cluster)
# Wizualizacja wyników PCA z analizą skupień
ggplot(pca_data, aes(x = PC1, y = PC2)) +
geom_point(aes(color = Cluster), size = 3) + # Punkty kolorowane według klastrów
geom_text(aes(label = Car), vjust = -0.5, hjust = 1.5, size = 3) +
theme_minimal() +
ggtitle("PCA z analizą skupień (K-means)") +
theme(axis.title = element_blank(), axis.text = element_blank()) +
scale_color_manual(values = c("red", "green", "blue"))
Jak widać, wyniki różnią się od poprzednich metod. Uwidaczniają się bardzo duże podobieństwa aut w grupie zielonej. Oto, więc ich wartości:
## mpg cyl disp hp drat wt qsec vs am gear carb
## Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
## Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
## Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
## Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
## Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
## Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
## Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
## Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
## Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
## AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
## Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
## Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
## [1] "Współczynnik zmienności dla samochodów w zielonym klastrze:"
## # A tibble: 11 × 2
## Variable CV
## <chr> <dbl>
## 1 mpg_cv 18.4
## 2 cyl_cv 0
## 3 disp_cv 20.1
## 4 hp_cv 17.2
## 5 drat_cv 7.38
## 6 wt_cv 18.7
## 7 qsec_cv 4.68
## 8 vs_cv NaN
## 9 am_cv NaN
## 10 gear_cv 0
## 11 carb_cv 29.2
Są pewne wartości, które są identyczne dla pewnych zmiennych. Współczynnik zmienności dla pięciu zmiennych jest większy niż 10%, lecz niższy niż 30% co wskazuje na umiarkowaną zmienność tych danych.
Zalety PCA:
usuwa wielowymiarowość
analiza identyfikuje korelacje między zmiennymi i tworzy nowe, niezależne zmienne (główne składowe), co eliminuje nadmiar informacji.
usuwa współzależność
redukuje wpływ szumu w danych, koncentrując się na najbardziej istotnych składnikach
Wady PCA:
brak interpretowalności danych, składniki główne są kombinacji oryginalnych zmiennych,
zmienne muszą być wysoko skorelowane ze sobą
jest metodą liniową, więc nie wychwyca nieliniowych zależności
normalność rozkładu zmiennych
wyniki tej metody są trudne do interpretacji
tylko dane metryczne
PCA działa lepiej na dużych zbiorach danych, ponieważ w małych próbkach wyniki mogą być niestabilne i niewiarygodne, co widać na przedstawionych zbiorze mtcars. Pomimo “przejścia” danych przez testy do PCA, nie zostały one tak dobrze pogrupowane jak w poprzednich metodach. Poprzez PCA zredukowaliśmy liczbę wymiarów, lecz poprzednie metody wydają się być lepiej dostosowane do danych mtcars.
| Kryterium | PCA | MDS | NMDS | Sammona |
|---|---|---|---|---|
| Typ danych | Metryczne | Metryczne | Porządkowe/niemetryczne | Metryczne |
| Zachowanie odległości | Przybliżone | Dokładne | Relatywne (porządek) | Dokładne lokalnie |
| Zachowanie wariancji | Tak | Nie | Nie | Nie |
| Założenie liniowości | Tak | Tak | Nie | Nie |
| Złożoność obliczeniowa | Niska | Średnia | Wysoka | Wysoka |
PCA sprawdza się w redukcji wymiarowości i analizie korelacji, gdy dane są liniowe i metryczne.
MDK (MDS) jest prostą metodą do analizy odległości, ale wymaga metrycznych miar i jest wrażliwa na szum.
NMDS jest elastyczna i efektywna w pracy z danymi porządkowymi lub niemetrycznymi, ale wymaga większych zasobów obliczeniowych.
Metoda Sammona jest przydatna, gdy zależy nam na zachowaniu lokalnych struktur danych, jednak jej zastosowanie jest ograniczone przez złożoność obliczeniową.
Do wybranego zbioru danych najlepiej sprawdziły się metody: klasycznego skalowania wielowymiarowego i skalowanie Sammona.